简单的天空盒和天空穹顶
天空盒:
- 使用一个立方体网格,纹理设置为所需环境,将立方体放在相机上。
- 禁用深度测试先渲染天空盒。
- 天空盒随相机移动。
天空穹顶:
- 区别是使用球体或者半球体代替立方体。
CubeMap实现天空盒
优点是可减少接缝以及支持环境贴图。
实现
- 网格创建和缓存区:
//天空盒网格 float cubeVertexPositions[108] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; glGenVertexArrays(1, vao); glBindVertexArray(vao[0]); glGenBuffers(numVBOs, vbo[99]); glBindBuffer(GL_ARRAY_BUFFER, vbo[99][0]); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertexPositions), cubeVertexPositions, GL_STATIC_DRAW);
- 渲染:
//********** 天空盒 ********************************* glUseProgram(renderingProgramCubemap); vLoc = glGetUniformLocation(renderingProgramCubemap, "v_matrix"); glUniformMatrix4fv(vLoc, 1, GL_FALSE, glm::value_ptr(vMat)); projLoc = glGetUniformLocation(renderingProgramCubemap, "p_matrix"); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat)); glBindBuffer(GL_ARRAY_BUFFER, vbo[99][0]); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, texSkybox); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); // cube is CW, but we are viewing the inside glDisable(GL_DEPTH_TEST); glDrawArrays(GL_TRIANGLES, 0, 36); glEnable(GL_DEPTH_TEST); //****************************************************
- 着色器: ```GLSL //vert shader: #version 430
layout (location = 0) in vec3 position; out vec3 cubetc;
uniform mat4 v_matrix; uniform mat4 p_matrix; layout (binding = 0) uniform samplerCube samp;
void main(void) { cubetc = position;//纹理坐标就是顶点坐标 mat4 v3_matrix = mat4(mat3(v_matrix));//去除V矩阵中的平移 gl_Position = p_matrix * v3_matrix * vec4(position,1.0); }
//frag shader: #version 430
in vec3 cubetc; out vec4 fragColor;
uniform mat4 v_matrix; uniform mat4 p_matrix; layout (binding = 0) uniform samplerCube samp;
void main(void) { fragColor = texture(samp,cubetc); }
<br />
# CubeMap实现环境贴图
程序:
```CPP
//...
//激活环境纹理
glActiveTexture(GL_TEXTURE???); //纹理单元1-绑定环境纹理
glBindTexture(GL_TEXTURE_CUBE_MAP, texSkybox);
//激活其他纹理...
//绘制...
着色器:
//片段着色器的部分代码
//...
layout(binding = 1) uniform samplerCube envTex;
//...
void main(void)
{
vec3 Nview = normalize(varyingNormal);
vec3 Lview = normalize((v_matrix * vec4(-light.dir, 0.0)).xyz);
vec3 Vview = normalize(-varyingPos);
vec3 Hview = normalize(Lview + Vview);
vec3 Rview = reflect(normalize(varyingPos), normalize(varyingNormal));
vec3 Rworld = (vec4(Rview, 0.0) * v_matrix).xyz;
vec4 env_color = texture(envTex,Rworld);
//...
//(可以视光滑/粗糙度进行滤波模糊)
}